package com.bplow.deep.base.concurrent.synclock;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.context.annotation.Role;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

@Configuration
public class SyncLockConfiguration implements ImportAware{

	protected AnnotationAttributes enableCaching;
	
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactorySyncLockOperationSourceAdvisor cacheAdvisor() {
		BeanFactorySyncLockOperationSourceAdvisor advisor =
				new BeanFactorySyncLockOperationSourceAdvisor();
		advisor.setSyncLockAttributeSource(syncLockOperationSource());
		advisor.setAdvice(cacheInterceptor());
		advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public SyncLockAttributeSource syncLockOperationSource() {
		return new AnnotationSyncLockAttributeSource();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public SyncLockInterceptor cacheInterceptor() {
		SyncLockInterceptor interceptor = new SyncLockInterceptor();
		interceptor.setSyncLockAttributeSource(syncLockOperationSource());
		return interceptor;
	}
	
	@Override
	public void setImportMetadata(AnnotationMetadata importMetadata) {
		this.enableCaching = AnnotationAttributes.fromMap(
				importMetadata.getAnnotationAttributes(EnableSyncLock.class.getName(), false));
		if (this.enableCaching == null) {
			throw new IllegalArgumentException(
					"@EnableSyncLock is not present on importing class " + importMetadata.getClassName());
		}
		
	}

}
